package itsur.arquitecturas.implicitinvocation;

/**************************************************************************************
** Class name: Communication
** Author: A.J. Lattanze
** Date: 12/29/99
** Version 1.0
***************************************************************************************
** Purpose: Assignment 3 for SE 17-655, Architectures for Software Systems. This object
** provides the basis of the implicit invocation communcations mechanisms
**
** Abstract: This class provides the observer/observable mechanism for the system
** components to use (through inheritance) to communication to other components.  If
** you refer to the architectural drawing, this class implements the virtual bus.
** When components inherit this class, they are effectively "plugging into" the virtual
** bus.  This class also makes the common data available to components as well.
**
** Modification Log
**************************************************************************************
**
**************************************************************************************/

import java.util.*;

public class Communication extends Observable implements Observer
{
	Integer RegistrationNumber;	// Registration number for the Object
	String ComponentName;		// Name of this component

	static CommonData SystemData = new CommonData(); 		// Provides access to system data
	static String SYSTEM_SHUT_DOWN = "ShutDown";			// Shutdown string.
	static Integer SYSTEM_SHUT_DOWN_ID = new Integer( 0 );	// The shutdown ID.

	// The constructor must receive a component registration number and a
	// component name.  This is a one-to-one mapping that is designed to ease
	// the use of the virtual bus.  Rather than have to remember numbers, components
	// can be referenced by name.  I used the declared name of the component, but you
	// don't have to (Keep in mind that this is the declared name, not the class type
	// name).

	public Communication( Integer RegistrationNumber, String ComponentName )
	{
		// Here we record our Component RegistrationNumber

		this.RegistrationNumber = new Integer(  RegistrationNumber.intValue() );
		this.ComponentName = ComponentName;
		SystemData.RegisterComponent( (Communication) this );

	} // Communication

	// Finds a component's registration ID given the component name.  This method
	// provides an interface for users so they don't directly access the common
	// data.

	public Integer GetComponentID( String ComponentName )
	{
		return( SystemData.GetComponentID( ComponentName ) );

	} // GetComponentID

	// Adds a Component to the list of Components that will receive signals
	// from this class.  This is done by adding the component name to the
	// Component list that is maintained in CommonData

	public void AddToReceiverList( String ComponentName )
	{
	   addObserver( (Observer) SystemData.GetComponent(ComponentName) );

	} // AddToReceiverList

	// Removes a Component from the list of Components that will respond to
	// signals.  This is done by removing the component name from the Component
	// list that is maintained in CommonData

	public void RemoveFromReceiverList( String ComponentName )
	{
	   deleteObserver( (Observer) SystemData.GetComponent(ComponentName) );

	} // AddToReceiverList

	// This method signals all components.  The only data that is passed along is
	// an Integer representing a component's ID.  This ID is the component name that
	// you intend to signal.  All components receive the signal, the responsibility
	// of the components to ignore or act upon the signal.  In the original system,
	// after a signal is received, the components checks to see if its their ID.  If
	// it is, they render service, otherwise they ignore the signal.

	public void SignalReceivers( String ComponentName )
	{
		setChanged();

		if (ComponentName.compareTo(SYSTEM_SHUT_DOWN) == 0 )
		{
			notifyObservers( SYSTEM_SHUT_DOWN_ID );

		} else {

			notifyObservers( SystemData.GetComponentID( ComponentName ) );

		} //if

	} // SignalReceivers

	// The update() method is an abstract method that is called whenever the
	// notifyObservers() method is called by the Observable class. This method
    // has to be implemented here because of the fact that this class implements
	// the Observer object  and the update method is an abstract method.  However,
	// the real work of update() has to be implemented in the class that inherits
	// this class. Implementing update in child object effectively over-rides
	// this update method which does nothing.

	public void update( Observable Thing, Object Item )
	{
	} // update

} // Communication